package org.idea.qiyu.framework.threadpool.dynamic.config;

import lombok.extern.slf4j.Slf4j;
import org.idea.qiyu.framework.threadpool.dynamic.executor.QiyuExecutor;
import org.idea.qiyu.framework.threadpool.dynamic.executor.QiyuThreadFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.concurrent.*;

/**
 * @Author linhao
 * @Date created in 10:22 上午 2021/10/26
 */
@Configuration
@EnableConfigurationProperties(value = QiyuDynamicThreadPoolProperties.class)
@Slf4j
public class QiyuDynamicThreadPoolAutoConfiguration implements InitializingBean {

    @Resource
    private QiyuDynamicThreadPoolProperties qiyuDynamicThreadPoolProperties;
    @Resource
    private DefaultListableBeanFactory defaultListableBeanFactory;
    @Resource
    private ApplicationContext applicationContext;

    public void refreshThreadPoolExecutor(QiyuDynamicThreadPoolProperties qiyuDynamicThreadPoolProperties) {
        for (IExecutors executor : qiyuDynamicThreadPoolProperties.getExecutors()) {
            BlockingQueue<Runnable> blockingQueue = executor.getQueueCapacity() > 0 ?
                    new ArrayBlockingQueue<>(executor.getQueueCapacity()) : new LinkedBlockingQueue<>();
            QiyuExecutor qiyuExecutor = new QiyuExecutor(executor.getCorePoolSize(),
                    executor.getMaximumPoolSize(),
                    executor.getKeepAliveTime(),
                    TimeUnit.MILLISECONDS,
                    blockingQueue,
                    new QiyuThreadFactory(executor.getName() + "-" + executor.getThreadPoolName()),
                    new ThreadPoolExecutor.AbortPolicy() // todo
                    );
            log.info("register thread pool executor !");
            defaultListableBeanFactory.registerSingleton(executor.getName(),qiyuExecutor);
            defaultListableBeanFactory.autowireBean(executor);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.refreshThreadPoolExecutor(qiyuDynamicThreadPoolProperties);
    }
}
